package com.easybuilder.common.config.filter;

import com.alibaba.fastjson.JSONObject;
import com.easybuilder.common.utils.ThreadPoolUtil;
import com.easybuilder.core.seo.entity.SysSeoHistory;
import com.easybuilder.core.seo.service.SeoHistoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

@Slf4j
@Component
public class SeoFilter implements Filter {

    @Resource
    private SeoHistoryService seoHistoryService;

    private static final String agents = "Baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|bingbot|Sosospider|Sogou Pic Spider|Googlebot|360Spider";
    private static  List<String> spiderAgents = new ArrayList<>();
    static {
        spiderAgents = Arrays.asList(agents.split("\\|"));
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        long start = System.currentTimeMillis();
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 抓取地址
        StringBuffer requestURL = request.getRequestURL();
        // 服务端口
        int serverPort = request.getServerPort();
        // 转换成代理类
        ResponseWrapper wrapperResponse = new ResponseWrapper(response);
        // 放过请求，继续执行后面的过滤器链
        filterChain.doFilter(request, wrapperResponse);
        byte[] content = wrapperResponse.getContent();
        String result = new String(content, "UTF-8");
        // 来源
        String agent = request.getHeader("User-Agent");
        // 如果是搜索引擎蜘蛛来抓取数据
        if (spiderAgents.contains(agent)) {
            // 请求参数
            Map<String, String[]> parameterMap = request.getParameterMap();
            // 如果请求路径中带#，在经过nginx转发后，会丢失#后面的路径
            log.info("抓取地址：{}", requestURL.toString());
            log.info("请求参数：{}", JSONObject.toJSONString(parameterMap));
            log.info("搜索引擎蜘蛛来源：{}", agent);
            // 构建参数
            buildParams(requestURL, parameterMap);
            log.info("最终抓取地址：{}", requestURL);
            log.info("渲染结果：{}", result);

            long useTime = System.currentTimeMillis() - start;
            // 保存seo抓取记录
            saveSeoHistory(requestURL, parameterMap, agent,  result, useTime);
            response.setContentType("text/html;charset=UTF-8");
        }

        response.setCharacterEncoding("utf-8");
        ServletOutputStream os = response.getOutputStream();
        os.write(content);
        os.flush();
    }


    /** 构建参数 */
    private void buildParams(StringBuffer requestURL, Map<String, String[]> parameterMap) {
        if (parameterMap.size() > 0) {
            Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
            int i = 0;
            for (Map.Entry<String, String[]> entry : entries) {
                String key = entry.getKey();
                String[] value = entry.getValue();
                if (i == 0) {
                    requestURL.append("?");
                } else {
                    requestURL.append("&");
                }
                requestURL.append(key).append("=").append(value[0]);
                i++;
            }
        }
    }


    /** 保存seo抓取记录 */
    private void saveSeoHistory(StringBuffer requestURL, Map<String, String[]> parameterMap, String agent, String result, Long useTime) {
        ThreadPoolUtil.getExecutor().execute(() -> {
            SysSeoHistory seoHistory = new SysSeoHistory();
            seoHistory.setUserAgent(agent);
            seoHistory.setRequestUrl(requestURL.toString());
            seoHistory.setRequestParams(JSONObject.toJSONString(parameterMap));
            seoHistory.setResult(result);
            seoHistory.setUseTime(useTime);
            seoHistory.setCreateTime(new Date());
            seoHistoryService.addSeoHistory(seoHistory);
            log.info("保存seo历史记录成功！");
        });
    }

    public static void main(String[] args)  {
        Process exec = null;
        try {
            exec = Runtime.getRuntime().exec("phantomjs ./spider.js http://localhost:8081/articleDetail.html?id=39");
            BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line = "";
            while ((line = br.readLine()) != null) {
                sb.append(new String(line.getBytes(), "utf-8"));
            }
            System.out.println(sb.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
